package com.petiot.rabbitmq;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.ContentHandler;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.UUID;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;

import com.petiot.rabbitmq.PushService.PushMsgCallback;
import com.petiot.ui.fragment.Home1Fra;
import com.petiot.ui.fragment.Home2Fra;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.AMQP.BasicProperties;

public class WavIoTDevice {
	  
    private String mGroupId;
    private String mDeviceUid;
    private String mLoginId;
    private String mLoginPwd;
    private String mQueueName;
    private static String mSessionKey;
    private int mHeartBeatTimer = -1;
    private boolean isLogin = false;
    private String mResponseQueue;
    private String mCorrId;
    private static final String TAG = "WavIoTDevice";
    private static final String EXCHANGE_NAME = "petiot.direct";
    private String waviot_hashkey = "wavcam2015";
	public static final String KEY_MAC = "HMACMD5";
    
    private PushService.PushMsgCallback pushMsgCallback;
	private WavIoTClient waviotClient;
	
    
	public WavIoTDevice(String groupId, String deviceUid, String id, String password,String responseQueue, PushMsgCallback callback)
	{
		mGroupId = groupId;
		mDeviceUid = deviceUid;
		mLoginId = id;
		mLoginPwd = password;
		mResponseQueue = responseQueue;
		isLogin = false;
		
		pushMsgCallback = callback;		    
	}
	public boolean isLogin()
	{
		return isLogin;
	}
	
	public String getSessionKey()
	{
		return mSessionKey;
	}
	

	public boolean isDeviceMsg(JSONObject jsonMsg) throws JSONException
	{
		if(jsonMsg.getJSONObject("header").getString("deviceID").equals(mDeviceUid))
		{
			return true;
		}else
		{
			return false;
		}
		
	}	

	//姣忓垎閽熸墽琛屼竴娆�
	public void doSession(Channel channel,String clientUid) throws IOException
	{
		System.out.println("3333333");
		if(!isLogin)
		{
			System.out.println("444444444");
			doLogin(channel, clientUid);
			return;
		}
		
		if(mHeartBeatTimer == 0)
		{
			isLogin = false;
			mHeartBeatTimer = -1;
			mCorrId = "";
			channel.queueUnbind(mResponseQueue, EXCHANGE_NAME, mSessionKey);
			Log.d(TAG, "mHeartBeatTimer : 0, Unbind sessionKey:" + mSessionKey+"; targetUid:" + mDeviceUid);
			mSessionKey = "";
			return;
		}
		
		if(mHeartBeatTimer > 0)
		{
			mHeartBeatTimer--;
			
			Log.d(TAG, " targetUid:"+mDeviceUid+" ;sessionKey:" + mSessionKey+" curHeartBeatTimer:" + mHeartBeatTimer);
			return;
		}
		
	}
/**	
	public void doFeeding(String action, Channel channel,String clientUid) throws IOException
	{
		String group_id = "A0000";
		String myclient_uid = "ZHUWEI_WAVIOT_VDEVICE_20151111_1";
        waviotClient = new WavIoTClient(group_id, myclient_uid);
		
		try {
			JSONObject motorMSG = make_getStatus_msg(action, channel, clientUid);
			//mSessionKey = "";
			mCorrId = UUID.randomUUID().toString();
			BasicProperties props = new BasicProperties.Builder()
			.correlationId(mCorrId).replyTo(mResponseQueue).build();
			
			Log.v(TAG, "EXCHANGE_NAME" + EXCHANGE_NAME);
			Log.v(TAG, "mDeviceUid" + mDeviceUid);
			Log.v(TAG, "motorMSG" + motorMSG.toString());
			Log.v(TAG, "motorMSG props" + props);
			
			channel.basicPublish(EXCHANGE_NAME,mDeviceUid, props, (motorMSG.toString()).getBytes("UTF-8"));
			Log.d(TAG, "perform motorMSG:" + mDeviceUid);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
**/	
	Thread connectionThread ;
	public void doFeeding(final String action, final Channel channel,final String clientUid) {
		// TODO Auto-generated method stub
		connectionThread = new Thread(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				try {
					JSONObject motorMSG = make_getStatus_msg(action, channel, clientUid);
					//mSessionKey = "";
					mCorrId = UUID.randomUUID().toString();
					BasicProperties props = new BasicProperties.Builder()
					.correlationId(mCorrId).replyTo(mResponseQueue).build();
					
					Log.v(TAG, "EXCHANGE_NAME" + EXCHANGE_NAME);
					Log.v(TAG, "mDeviceUid" + mDeviceUid);
					Log.v(TAG, "motorMSG" + motorMSG.toString());
					Log.v(TAG, "motorMSG props" + props);
					
					channel.basicPublish(EXCHANGE_NAME,mDeviceUid, props, (motorMSG.toString()).getBytes("UTF-8"));
					Log.d(TAG, "perform motorMSG:" + mDeviceUid);
				} catch (UnsupportedEncodingException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
		connectionThread.start();
	}
	
	protected JSONObject make_getStatus_msg(String action, Channel channel, String clientUid) {
		// TODO Auto-generated method stub
		Date now = new Date();
		SimpleDateFormat ft = new SimpleDateFormat("yyyyMMddHHmmss");
		String DateTime = ft.format(now);
		JSONObject jsonObj = null;
		try {
			jsonObj = new JSONObject();
			JSONObject body = new JSONObject();
			body.put("targetUID", clientUid);
			Log.e(TAG, "mSessionKey = " + mSessionKey);
			body.put("sessionKey", mSessionKey);
			byte[] Code = null;
			String hashcode = null;
			try {
				Code = encryptHMAC((action + clientUid).getBytes(), waviot_hashkey);
				Log.e("=======", "hashcode = " + Code);
				hashcode = Base64.encodeToString(Code, Base64.DEFAULT);
				// String hashcode = new BASE64Encoder().encode(Code);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			JSONObject header = new JSONObject();
			header.put("msgID", "getStatus");
			header.put("action", action);
			header.put("msgTime", DateTime);
			header.put("groupId", "A0000");
			header.put("deviceId", clientUid);
			header.put("ipAddress", "");
			header.put("authKey", "RFU");
			header.put("hashCode", hashcode);
			jsonObj.put("header", header);
			jsonObj.put("body", body);
			jsonObj.put("waviot", "1.0");
			System.out.println(jsonObj);
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Log.e("2.2.2.2", "setupObverse button json = " + jsonObj);
		return jsonObj;
	}
	
	
	/**
	 *@param clientUid锛岀敤鏉ユ斁鍦ㄥご閮ㄧ殑锛屾爣璇咥pp瀹㈡埛绔紝涓嶆槸鏍囪瘑璁惧 
	 */
	public void doLogin(Channel channel, String clientUid)
	{
		System.out.println("55555555555");
		if(isLogin)
		{
			return;
		}else
		{
	
	try {
		String loginMsg = make_reqLogin_msg(mDeviceUid, mLoginId,mLoginPwd);
		mSessionKey = "";
		mCorrId = UUID.randomUUID().toString();
		BasicProperties props = new BasicProperties.Builder()
		.correlationId(mCorrId).replyTo(mResponseQueue).build();
		
		Log.v(TAG, "EXCHANGE_NAME" + EXCHANGE_NAME);
		Log.v(TAG, "mDeviceUid" + mDeviceUid);
		Log.v(TAG, "loginMsg" + loginMsg);
		Log.v(TAG, "props" + props);
		
		Log.e(TAG, "1111 channel = " + channel);
		
		channel.basicPublish(EXCHANGE_NAME,mDeviceUid, props,loginMsg.getBytes("UTF-8"));
		Log.d(TAG, "perform login:" + mDeviceUid);
		Log.e(TAG, "2222 channel = " + channel);
	} catch (UnsupportedEncodingException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
		}
	}


	public void msgHandler(Channel channel , java.lang.String consumerTag,Envelope envelope,AMQP.BasicProperties properties,
                JSONObject body) throws IOException
	{
		try {
			String msgValue = body.getJSONObject("header").getString("msgID");
			if(msgValue.equals("resLogin"))
			{
				Log.v(TAG, "收到成功登录的消息，表示该手机已经成功连接该设备。");
				dealWithresLogin(channel,consumerTag,envelope,properties,body);
				//pushMsgCallback.doresLogin(channel,consumerTag,envelope,properties,body);
			 
			}else if(msgValue.equals("heartbeat"))
			{
				Log.v(TAG, "收到心跳，应该做一些回调的事情");
				//pushMsgCallback.callBack(body.toString(), mDeviceUid);
			}else if(msgValue.equals("error"))
			{
				pushMsgCallback.callBack(body.toString(), mDeviceUid);
				msgError(body);
			}else if(msgValue.equals("deviceStatus"))
			{
				pushMsgCallback.callBack(body.toString(), mDeviceUid);
				String Myresult = body.getJSONObject("body").getString("Content");
				Home1Fra result = new Home1Fra();
				result.callBack(Myresult);
			}else if(msgValue.equals("resSqlite"))
			{
				Log.v(TAG, "收到了数据库里的内容了，应该做一些回调的事情");
				//String msgSqlite = body.getJSONObject("body").getString("Content");
				JSONObject content = body.getJSONObject("content");
				Log.v("收到了数据库里的内容", "数据库里的内容是 = " + content);
				Home2Fra canvas = new Home2Fra();
				canvas.drawTable(content);
				//pushMsgCallback.callBack(msgSqlite, mDeviceUid);
			}else if(msgValue.equals("ipcamFirmware"))
			{
				pushMsgCallback.callBack(body.toString(), mDeviceUid);
			}
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	

	private void msgError(JSONObject msg) throws JSONException
	{
		Log.e(TAG, mDeviceUid+", error: " + msg.getJSONObject("body").getString("errno"));
	}
	
	private boolean dealWithresLogin(Channel channel ,java.lang.String consumerTag,Envelope envelope,AMQP.BasicProperties properties,
            JSONObject body) throws JSONException, IOException
	{
		String corrId = properties.getCorrelationId();
		if(!mCorrId.equals(corrId))
		{
			Log.e(TAG,  "curUid: " + mDeviceUid+",corr_id :"+mCorrId+" , is not matched " + corrId);
			return false;
		}
		

		if(body.getJSONObject("body").getString("retCode").equals("0000"))
		{
			JSONObject jsonBody = body.getJSONObject("body");
			mSessionKey = jsonBody.getString("sessionKey");
			isLogin = true;
			mHeartBeatTimer =jsonBody.getInt("heartbeatPeriod");
			Log.e(TAG, "3333 channel = " + channel);
			channel.queueBind(mResponseQueue, EXCHANGE_NAME, mSessionKey);
			Log.d(TAG, "successfully login, targetUID:" + mDeviceUid);
			Log.e(TAG, "4444 channel = " + channel);
			return true;
		}
		
		
		
		return false;
	}
	

	public static byte[] encryptHMAC(byte[] data, String key) throws Exception {
		SecretKey sk = new SecretKeySpec(key.getBytes(), KEY_MAC);
		Mac mac = Mac.getInstance(sk.getAlgorithm());
		mac.init(sk);
		return mac.doFinal(data);
	}

	private String make_reqLogin_msg(String targetUID, String id,
			String password) {
		Date now = new Date();
		SimpleDateFormat ft = new SimpleDateFormat("yyyyMMddHHmmss");
		String DateTime = ft.format(now);
		JSONObject jsonObj = null;
		try {
			jsonObj = new JSONObject();
			JSONObject body = new JSONObject();
			body.put("targetUID", targetUID);
			body.put("id", id);
			body.put("password", password);
			byte[] Code = null;
			String hashcode = null;
			try {
				Code = encryptHMAC((id + password).getBytes(), waviot_hashkey);
				Log.e("=======", "hashcode = " + Code);
				hashcode = Base64.encodeToString(Code, Base64.DEFAULT);
				// String hashcode = new BASE64Encoder().encode(Code);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			JSONObject header = new JSONObject();
			header.put("msgID", "reqLogin");
			header.put("msgTime", DateTime);
			header.put("groupId", "A000");
			header.put("deviceId", targetUID);
			header.put("ipAddress", "");
			header.put("authKey", "RFU");
			header.put("hashCode", hashcode);
			jsonObj.put("header", header);
			jsonObj.put("body", body);
			jsonObj.put("waviot", "1.0");
			System.out.println("jsonObj = " + jsonObj);
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return jsonObj.toString();
	}
	/**
	private JSONObject make_reqLogin_body(String targetUID, String id,
			String pwd) {

		try {

			
			JSONObject body = new JSONObject();
			body.put("targetUID", targetUID);
			body.put("id", id);
			body.put("password", pwd);
			
			return body;
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return null;
	}
	
	private JSONObject make_header(String msgID, String groupID,
			String deviceID, String ipAddress, String hashCode) {

		try {
			JSONObject header = new JSONObject();
			header.put("msgID", msgID);
			header.put("hashcode", hashCode);
			header.put("deviceID", deviceID);
			header.put("ipAddress", ipAddress);
			header.put("groupID", groupID);
			header.put("msgTime", getCurrentTime());

			return header;
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return null;
	}
	
	private String getCurrentTime() {
		Calendar calendar = Calendar.getInstance();
		Date date = calendar.getTime();

		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMDDHHmmss");
		return sdf.format(date);
	}
	


	

	
	
	private String getCurrentDeviceID() {
			String address = UUID.randomUUID().toString();
			return address;
	}
	**/
}
